package com.luke.star.util;

import java.lang.reflect.Field;
import java.util.Set;
import java.util.regex.Pattern;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.springframework.util.StringUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ReqCheckUtil {
	private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
	
	public static <T> String getValidator(T t) {

		//首先对List结果集中的数据进行校验   递归调用将会检查所有的结果集
		Field[] fields = t.getClass().getDeclaredFields();
		for(Field field:fields){
			field.setAccessible(true);
			try {
				Object obj = field.get(t);
				if(obj != null && obj instanceof java.util.List<?>){
					java.util.List<?> list = (java.util.List<?>)obj;
					for(Object e:list){
						
						String ret =  getValidator(e);
						if(!StringUtils.isEmpty(ret))
							continue;
						else
							return ret;
					}
				}
				if(field.getType()== String.class){
					field.set(t, stripXSS((String) field.get(t)));
				}
			} catch (IllegalArgumentException e) {
				log.error("",e);
			} catch (IllegalAccessException e) {
				log.error("",e);
			}
		}
		
		StringBuffer buf = new StringBuffer();
		int i = 0;

		Validator validator = factory.getValidator();
		
		Set<ConstraintViolation<T>> violations = validator.validate(t);
		if (violations.size() != 0) {
			for (ConstraintViolation<T> violation : violations) {
				if (i == 0) {
					i++;
					buf.append(violation.getMessage());
				} else {
					buf.append("|");
					buf.append(violation.getMessage());
				}
			}
		}
		return buf.toString();
	}
	
	private static String stripXSS(String value) {
		if (value != null) {
			value = value.replaceAll("", "");
			// Avoid anything between script tags
			Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>",Pattern.CASE_INSENSITIVE);
			value = scriptPattern.matcher(value).replaceAll("");
			// Avoid anything in a src="..." type of e­xpression
			scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
			value = scriptPattern.matcher(value).replaceAll("");
			scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE| Pattern.DOTALL);
			value = scriptPattern.matcher(value).replaceAll("");
			// Remove any lonesome </script> tag
			scriptPattern = Pattern.compile("</script>",Pattern.CASE_INSENSITIVE);
			value = scriptPattern.matcher(value).replaceAll("");
			// Remove any lonesome <script ...> tag
			scriptPattern = Pattern.compile("<script(.*?)>",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE| Pattern.DOTALL);
			value = scriptPattern.matcher(value).replaceAll("");
			// Avoid eval(...) e­xpressions
			scriptPattern = Pattern.compile("eval\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
			value = scriptPattern.matcher(value).replaceAll("");
			// Avoid e­xpression(...) e­xpressions
			scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
			value = scriptPattern.matcher(value).replaceAll("");
			// Avoid javascript:... e­xpressions
			scriptPattern = Pattern.compile("javascript:",Pattern.CASE_INSENSITIVE);
			value = scriptPattern.matcher(value).replaceAll("");
			// Avoid vbscript:... e­xpressions
			scriptPattern = Pattern.compile("vbscript:",Pattern.CASE_INSENSITIVE);
			value = scriptPattern.matcher(value).replaceAll("");
			// Avoid onload= e­xpressions
			scriptPattern = Pattern.compile("onload(.*?)=",	Pattern.CASE_INSENSITIVE | Pattern.MULTILINE| Pattern.DOTALL);
			value = scriptPattern.matcher(value).replaceAll("");
		}
		return value;
	}	
	
}
